#include "urltask.h"

#include <QDebug>
#include <QNetworkReply>
#include <QNetworkRequest>

UrlTask::UrlTask(const QString &url
                 , const QString &file
                 , UrlTask::TaskStatus status
                 , QNetworkAccessManager *manager, QObject *parent)
    : QObject(parent)
    , m_url(url)
    , m_file(new QFile(file))
    , m_progress(0)
    , m_status(status)
    , m_manager(manager)
    , m_reply(0)
{}

UrlTask::~UrlTask()
{
    close();
}

UrlTask::UrlTask(QObject *parent) : QObject(parent) {}

UrlTask::UrlTask(const UrlTask &task)
    : QObject(task.parent())
    , m_url(task.m_url)
    , m_file(task.m_file)
    , m_progress(task.m_progress)
    , m_status(task.m_status)
    , m_manager(task.m_manager)
    , m_reply(task.m_reply)
{}

UrlTask &UrlTask::operator=(const UrlTask &task)
{
    if (this != &task)
    {
        m_url = task.m_url;
        m_file = task.m_file;
        m_progress = task.m_progress;
        m_status = task.m_status;
        m_manager = task.m_manager;
        m_reply = task.m_reply;
    }
    return *this;
}

QString UrlTask::get_url() const
{
    return m_url.toString();
}

QString UrlTask::get_file() const
{
    return m_file->fileName();
}

quint8 UrlTask::get_progress() const
{
    return m_progress;
}

UrlTask::TaskStatus UrlTask::get_status() const
{
    return m_status;
}

void UrlTask::start_task()
{
    if (!m_reply && m_file->open(QIODevice::WriteOnly))
    {
        QNetworkRequest request(m_url);
        m_reply = m_manager->get(request);
        connect(m_reply, SIGNAL(readyRead()), this, SLOT(data_ready()));
        connect(m_reply, SIGNAL(finished()), this, SLOT(download_finished()));
        connect(m_reply, SIGNAL(downloadProgress(qint64,qint64))
                , this, SLOT(progress_changed(qint64,qint64)));
        m_status = INPROGRESS;
        emit task_changed(*this);
    }
}

void UrlTask::stop_task()
{
    close();
    emit task_changed(*this);
}

bool UrlTask::operator ==(const UrlTask &task) const
{
    return (get_url() == task.get_url()) && (get_file() == task.get_file());
}

void UrlTask::report_error(const QString &err)
{
    qDebug() << "ERROR: " << err;
    close();
    m_status = ERROR;
}

void UrlTask::close()
{
    if (m_file->isOpen()) m_file->close();
    if (m_reply)
    {
        m_reply->close();
        m_reply->deleteLater();
        m_reply = 0;
    }
}

void UrlTask::progress_changed(qint64 recv, qint64 total)
{
    if (total > 0) m_progress = static_cast<quint8>((recv * 100.0)/total);
    else m_progress = 0;
    emit task_changed(*this);
}

void UrlTask::data_ready()
{
    if (m_file->isOpen() && m_reply)
    {
        QByteArray buffer = m_reply->readAll();
        m_file->write(buffer);
    }
    else
    {
        report_error(tr("cannot save received data to file", "error"));
        emit task_changed(*this);
    }
}

void UrlTask::download_finished()
{
    close();
    m_status = FINISHED;
    emit task_changed(*this);
}
